#include "tool.h"

/**********************************************************************
 * 函数名称： // LS_handle
 * 功能描述： // LS命令
 * 访问的表： // fileInfo
 * 修改的表： // NULL
 * 输入参数： // const char* p_user, const char *p_name, int netfd
 * 返回的值： // 正确返回0， 错误返回1
 * 更新说明： // 输出按字典顺序排序
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2023/04/16       V3.4       zhao            XXXX
 ***********************************************************************/
int LS_handle(const char* p_user, const char *p_name, int netfd) {
    train_t train;
    bzero(train.data, sizeof(train.data));

    MYSQL * mysql = mysql_init(NULL); // 为mysql连接分配内存（线程不安全）

    MYSQL * ret = mysql_real_connect(mysql,"localhost", "root", "123456", "test", 0, NULL, 0);  //密码、数据库名可能不同
    if(ret == NULL){
        train.length = -1;
        sprintf(train.data, "mysql connect error:%s\n", mysql_error(mysql));
        send(netfd,&train,sizeof(train),0);
        SYSLOG(p_user, "LS", p_name,"fail");
        return -1;
    }

    char sql[1024] = "select name, id, pre_id, user, tomb from fileInfo ORDER BY name;";
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr,"sql error:%s\n", mysql_error(mysql));
        train.length = -1;
        sprintf(train.data, "mysql connect error:%s\n", mysql_error(mysql));
        send(netfd,&train,sizeof(train),0);
        SYSLOG(p_user, "LS", p_name,"fail");
        return -1;
    }

    MYSQL_RES *result = mysql_store_result(mysql); //取出读取的结果
    char buf[30] = {0};
    MYSQL_ROW row1, row2; //MYSQL_ROW 为char**

    unsigned int temp = 1;
    while((row1 = mysql_fetch_row(result)) != NULL){
        bzero(buf, sizeof(buf));
        if(strcmp(row1[0], p_name) == 0 && strcmp(row1[3], p_user) == 0) {
            strcpy(buf, row1[1]);
            break;
        }else {
            temp++;
            if(temp == mysql_num_fields(result)) {
                train.length = -1;
                sprintf(train.data, "%s is empty\n", p_name);
                send(netfd,&train,sizeof(train),0);
                SYSLOG(p_user, "LS", p_name,"fail");
            }
            continue;
        }
    }

    char info[1024] = {0};
    while((row2 = mysql_fetch_row(result)) != NULL){
        bzero(info, sizeof(info));
        if(strcmp(row2[2], buf) == 0 && strcmp(row2[3], p_user) == 0 && atoi(row2[4]) != 1) {
            sprintf(info, "%s%c", row2[0], ' ');
            strcat(train.data, info);
        }else {
            continue;
        }
    }

    train.length = 0;
    send(netfd,&train,sizeof(train),0);
    SYSLOG(p_user, "LS", p_name,"success");

    mysql_free_result(result);
    mysql_close(mysql);
    return 0;
}

/**********************************************************************
 * 函数名称： // logout
 * 功能描述： // 注销用户
 * 访问的表： // fielInfo, password
 * 修改的表： // fielInfo, password
 * 输入参数： // const char* p_user, int netfd
 * 返回的值： // 正确返回0， 错误返回1
 * 更新说明： //
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2023/04/16       V3.0       zhao            XXXX
 ***********************************************************************/

int helper(const char* table, const char * p_user, int netfd){
    MYSQL * mysql = mysql_init(NULL); // 为mysql连接分配内存（线程不安全）

    MYSQL * ret = mysql_real_connect(mysql,"localhost", "root", "123456", "test", 0, NULL, 0);
    train_t train;
    if(ret == NULL){
        train.length = -1;
        fprintf(stderr,"mysql connect error:%s\n", mysql_error(mysql));
        sprintf(train.data, "mysql connect error:%s\n", mysql_error(mysql));
        send(netfd,&train,sizeof(train),0);
        return -1;
    }

    char sql[1024] = {0};
    sprintf(sql, "UPDATE %s SET tomb = 1 WHERE user = %s;", table, p_user);

    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        train.length = -1;
        fprintf(stderr,"sql error:%s\n", mysql_error(mysql));
        sprintf(train.data, "mysql connect error:%s\n", mysql_error(mysql));
        send(netfd,&train,sizeof(train),0);
        return -1;
    }else {
        train.length = 0;
        sprintf(train.data, "drop success\n");
        send(netfd,&train,sizeof(train),0);
        return -1;
    }

    mysql_close(mysql);
    return 0;
}

int SIGN_OUT_handle(const char * p_user, int netfd){
    helper("fileInfo", p_user, netfd);
    helper("password", p_user, netfd);
    return 0;
}


/**********************************************************************
 * 函数名称： // LOGIN_handle
 * 功能描述： // 密码验证
 * 访问的表： // password
 * 修改的表： // NULL
 * 输入参数： // const char* p_user, const char *p_passwd, int netfd
 * 返回的值： // 正确返回0， 错误返回1
 * 更新说明： // 表中增加了墓地列，可以判断用户是否存在
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2023/04/16       V3.2       zhao            XXXX
 ***********************************************************************/

int LOGIN_handle(const char * p_user, const char * p_passwd, int netfd) {
    MYSQL * mysql = mysql_init(NULL); // 为mysql连接分配内存（线程不安全）
    MYSQL * ret = mysql_real_connect(mysql,"localhost", "root", "123456", "test", 0, NULL, 0);
    train_t train;
    if(ret == NULL){
        train.length = -1;
        fprintf(stderr,"mysql connect error:%s\n", mysql_error(mysql));
        sprintf(train.data, "mysql connect error:%s\n", mysql_error(mysql));
        send(netfd,&train,sizeof(train),0);
        return -1;
    }
    
    train_t train;
    char sql[1024] = "select user, salt, passwd, tomb from password;";
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        train.length = -1;
        fprintf(stderr,"sql error:%s\n", mysql_error(mysql));
        sprintf(train.data, "mysql connect error:%s\n", mysql_error(mysql));
        send(netfd,&train,sizeof(train),0);
        return -1;
    }

    MYSQL_RES *result = mysql_store_result(mysql); //取出读取的结果
    char salt[30] = {0};
    char passwd[30] = {0};
    MYSQL_ROW row; //MYSQL_ROW 为char**

    unsigned int temp = 1;
    while((row = mysql_fetch_row(result)) != NULL){
        bzero(salt, sizeof(salt));
        bzero(passwd, sizeof(passwd));
        
        if(strcmp(row[0], p_user) == 0 && atoi(row[3]) != 1) {
            strcpy(salt, row[1]);
            strcpy(passwd, row[2]);

            if(strcmp(crypt(p_passwd, salt), passwd) == 0){
                train.length = 0;
                sprintf(train.data, "passwd success\n");
                send(netfd,&train,sizeof(train),0);
            }else{
                train.length=-1;
                sprintf(train.data,"passwd failed\n");
                send(netfd,&train,sizeof(train),0);
            }
            break;
        }else {
            temp++;
            if(temp == mysql_num_fields(result)) {
                train.length = -1;
                sprintf(train.data, "not find %s\n", p_user);
                send(netfd,&train,sizeof(train),0);
            }
            continue;
        }
    }
    
    mysql_free_result(result);
    mysql_close(mysql);
    return 0;
}

/**********************************************************************
 * 函数名称： // SIGN_IN_handle
 * 功能描述： // 用户注册
 * 访问的表： // password, fileInfo
 * 修改的表： // password, fileInfo
 * 输入参数： // const char* p_user, const char *p_passwd, int netfd
 * 返回的值： // 正确返回0， 错误返回1
 * 更新说明： //
 * 修改日期        版本号     修改人          修改内容
 * -----------------------------------------------
 * 2023/04/16       V3.0       zhao            XXXX
 ***********************************************************************/

#define STR_LEN 10

char *GenerateStr(char *str){
    int i,flag;
    srand(time(NULL));//通过时间函数设置随机数种子，使得每次运行结果随机。
    for(i = 0; i < STR_LEN; i ++){
        flag = rand()%3;
        switch(flag){
        case 0:
            str[i] = rand()%26 + 'a';
            break;
        case 1:
            str[i] = rand()%26 + 'A';
            break;
        case 2:
            str[i] = rand()%10 + '0';
            break;
        }
    }
    return str;
}

int SIGN_IN_handle(const char * p_user, const char * p_passwd, int netfd){
    MYSQL * mysql = mysql_init(NULL); // 为mysql连接分配内存（线程不安全）
    train_t train;
    
    MYSQL * ret = mysql_real_connect(mysql,"localhost", "root", "123456", "test", 0, NULL, 0);
    if(ret == NULL){
        train.length = -1;
        fprintf(stderr,"mysql connect error:%s\n", mysql_error(mysql));
        sprintf(train.data, "mysql connect error:%s\n", mysql_error(mysql));
        send(netfd,&train,sizeof(train),0);
        return -1;
    }

    char str[STR_LEN + 1] = {0};
    char salt[STR_LEN + 1] = {0};
    char sql1[1024] = {0};
    char sql2[1024] = {0};
    strcpy(salt,  GenerateStr(str));
    
    sprintf(sql1, "INSERT INTO password (user, salt, passwd, tomb) VALUES('%s', '%s', '%s' ,0);"
            , p_user, salt, crypt(p_passwd, salt));
    sprintf(sql2, "INSERT INTO fileInfo (name, user, pre_id, type, md5, tomb, path, sign) VALUES('%s', '%s', %d, '%s', NULL, 0, '/%s', '%s');" 
            , p_user, p_user, -1, "d", p_user, "curpath") ;

    int qret1 = mysql_query(mysql,sql1);
    int qret2 = mysql_query(mysql,sql2);
    if(qret1 != 0 || qret2 != 0){
        train.length = -1;
        fprintf(stderr,"sql error:%s\n", mysql_error(mysql));
        sprintf(train.data, "mysql connect error:%s\n", mysql_error(mysql));
        send(netfd,&train,sizeof(train),0);
        return -1;
    }else {
        train.length = 0;
        sprintf(train.data, "passwd success\n");
        send(netfd,&train,sizeof(train),0);
    }

    mysql_close(mysql);
    return 0;
}


